Skip to content

Fix auto-optimisation direction for Bactrian scale factor (#96)#97

Merged
alexeid merged 2 commits into
masterfrom
fix-bactrian-scale-optimise-direction
Jun 17, 2026
Merged

Fix auto-optimisation direction for Bactrian scale factor (#96)#97
alexeid merged 2 commits into
masterfrom
fix-bactrian-scale-optimise-direction

Conversation

@alexeid

@alexeid alexeid commented Jun 17, 2026

Copy link
Copy Markdown
Member

Fixes #96.

The spec scale operators draw from a Bactrian kernel (scale = exp(scaleFactor * N(0,1))), so larger scaleFactor means larger jumps / lower acceptance — the opposite of the legacy ScaleOperator.

Changes

  • AbstractScale.optimize() tunes multiplicatively in the kernel direction (sf *= exp(delta)): acceptance too high increases the scale factor, too low decreases it. The old legacy transform ran the optimiser backwards and went NaN for scaleFactor >= 1.
  • The scale factor upper limit defaults to 10.0 directly in AbstractScale and IntervalScaleOperator, giving the optimiser the headroom it needs above 1. This removes the brittle initAndValidate hack that bumped the legacy 1 - 1e-8 default to 10.0 via a floating-point equality check (which also silently overrode a deliberate user value).
  • Removed the now-redundant optimize() override in ScaleOperator.
  • Corrected the scaleFactor input descriptions, which documented the inverted legacy semantics.

IntervalScaleOperator extends TreeOperator (separate hierarchy); its optimize() already tuned in the correct direction but its upper limit was still capped at ~1.0, so it is fixed here too.

Testing

mvn -pl beast-base compile succeeds.

AbstractScale.optimize() used the legacy ScaleOperator transform, which
assumes scaleFactor close to 0 means large jumps. The Bactrian kernel has
the opposite relationship (scale = exp(scaleFactor * N(0,1)), so larger
scaleFactor means larger jumps), making auto-optimisation run backwards for
operators that inherit the base method (e.g. ScaleTreeOperator): low
acceptance increased the scale factor instead of decreasing it, and the
transform went NaN for scaleFactor >= 1.

Tune multiplicatively in the kernel direction (sf *= exp(delta)), matching
the form already used by the ScaleOperator and IntervalScaleOperator
overrides. The redundant override in ScaleOperator is removed, and the
scaleFactor input description is corrected.

Fixes #96
@alexeid alexeid requested a review from jordandouglas June 17, 2026 01:23
@jordandouglas

Copy link
Copy Markdown
Member

This looks good to me. I am surprised this was unnoticed for so long

Default the upper limit to 10.0 directly in AbstractScale and
IntervalScaleOperator, and remove the brittle initAndValidate hack that
bumped the legacy 1-1e-8 default to 10.0 via a floating-point equality
check (which also silently overrode a deliberate user value). Correct
the IntervalScaleOperator scaleFactor description to match the Bactrian
semantics.
@alexeid alexeid merged commit 7dc2474 into master Jun 17, 2026
1 check passed
@alexeid alexeid deleted the fix-bactrian-scale-optimise-direction branch June 17, 2026 02:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Auto-optimisation tunes Bactrian scale factor in the wrong direction in AbstractScale

2 participants